﻿
Imports std
Imports xmlctrl
Imports xhtmlctrl
Imports webctrl
Imports wfileis.data

Public MustInherit Class previewPage
    Inherits cacheControlProcessor

    Protected Overrides Function normalRetiredTicks() As Int64
        Return secondsToTicks(5)
    End Function

    Private Class config
        Public Shared topiccount As Int64
        Public Shared topiclength As Int64
        Public Shared recentDropdownListLength As Int64
    End Class

    Public MustOverride Overrides Function pathidentity() As String

    Public Overrides Sub initial(Optional ByVal iconfig As configParser = Nothing)
        MyBase.initial(iconfig)
        assert(Not iconfig Is Nothing, "previewPage needs a valid configParser to initialize.")
        config.topiccount = iconfig.parameter(configNaming.previewPage.name, _
                                              configNaming.previewPage.topiccount, _
                                              configNaming.defaultValue.previewPage.topiccount)
        config.topiclength = iconfig.parameter(configNaming.previewPage.name, _
                                              configNaming.previewPage.topiclength, _
                                              configNaming.defaultValue.previewPage.topiclength)
        config.recentDropdownListLength = _
            iconfig.parameter(configNaming.previewPage.name, _
                              configNaming.previewPage.recentDropdownListLength, _
                              configNaming.defaultValue.previewPage.recentDropdownListLength)
    End Sub

    Protected Shared Sub processTopic(ByVal key As String, ByVal record As record, _
                                      ByVal infos As vector(Of pointer(Of info)), _
                                      ByVal page As xhtmlpage, ByVal root As xmlcontrol)
        processPreview(httpServer2.currentContext(), key, record, infos, page, root, config.topiclength)
    End Sub

    Protected Shared Sub processFailedTopic(ByVal key As String, ByVal page As xhtmlpage, ByVal root As xmlcontrol)
        Dim context As httpContext = Nothing
        context = httpServer2.currentContext()
        Dim comment As comment = Nothing
        comment = context.createControl(New comment())
        comment.text = context.string(stringId.VIEW_FAILREADINFO) + " [" + key + "]"
        root.addchild(comment)
    End Sub

    Protected Shared Sub processNoContent(ByVal page As xhtmlpage, ByVal root As xmlcontrol)
        root.addchild(httpServer2.currentContext().createControl(New lpmsengi.nameLpmsControl(page, "nothingmore")))
    End Sub

    Protected Shared Sub processTopics(ByVal context As httpContext, _
                                       ByVal page As xhtmlpage, _
                                       ByVal root As xmlcontrol, _
                                       ByVal records As list(Of String))
        If records Is Nothing OrElse records.size() = 0 Then
            processNoContent(page, root)
        Else
            Dim it As list(Of String).iterator = Nothing
            Dim s As [set](Of String) = Nothing
            s = New [set](Of String)()
            it = records.begin()
            While it <> records.end()
                If s.find(+it) = s.end() Then
#If RETIRED Then
                    Dim record As record = Nothing
                    record = New record()
                    Dim recv As vector(Of String) = Nothing
                    If record.read(+it) AndAlso list2vector(record, recv) AndAlso _
                       sort(recv.rawdata(), 0, recv.size()) AndAlso recv.size() > 0 Then
                        Dim infos As vector(Of pointer(Of info)) = Nothing
                        infos = New vector(Of pointer(Of info))()
                        Dim info As info = Nothing
                        info = New info()
                        insertInfo(infos, recv(0))

                        'since cannot get user names before read it, so insert at most last two infos
                        If recv.size() > 2 Then
                            insertInfo(infos, recv(recv.size() - 2))
                        End If
                        If recv.size() > 1 Then
                            insertInfo(infos, recv(recv.size() - 1))
                        End If
                        processTopic(+it, record, infos, page, root)
                    Else
                        raiseError("cannot read record " + (+it) + ", or cannot list2vector, " + _
                                   "or cannot sort, or empty.", errorHandle.errorType.warning)
                        processFailedTopic((+it), page, root)
                    End If
#End If
                    Dim record As record = Nothing
                    Dim infos As vector(Of pointer(Of info)) = Nothing
                    If prepareInfos(+it, record, infos) Then
                        processTopic(+it, record, infos, page, root)
                    Else
                        raiseError(errorHandle.errorType.warning, "cannot process topic ", +it)
                        processFailedTopic(+it, page, root)
                    End If
                    s.insert(+it)
                End If
                it += 1
            End While
        End If
    End Sub

    Protected Overridable Function topics(ByVal start As Int64, ByVal count As Int64) As list(Of String)
        Return Nothing
    End Function

    Protected Overridable Sub processTopics(ByVal context As httpContext, _
                                            ByVal page As xhtmlpage, _
                                            ByVal root As xmlcontrol, _
                                            ByVal start As Int64, _
                                            ByVal count As Int64, _
                                            ByRef nomore As Boolean)
        Dim l As list(Of String) = Nothing
        l = topics(start, count)
        processTopics(context, page, root, l)
        nomore = ((l Is Nothing) OrElse (l.size() < count))
    End Sub

    Private Shared Sub processDescription(ByVal context As httpContext, _
                                          ByVal page As xhtmlpage, ByVal root As xmlcontrol)
        assert(Not context Is Nothing, "context is nothing.")
        assert(Not page Is Nothing, "page is nothing.")
        assert(Not root Is Nothing, "root is nothing.")

        Dim ul As ul = Nothing
        ul = context.createControl(New ul())
        ul.class = "brdbtm"
        root.addchild(ul)

        Dim li As li = Nothing
        li = context.createControl(New colorli(page))
        ul.addchild(li)

        Dim xmltext As xmltext = Nothing
        xmltext = context.createControl(New xmltext())
        xmltext.text = context.string(stringId.HOMEPAGE_SEARCHCATEGORY)
        li.addchild(xmltext)

        Dim form As form = Nothing
        form = context.createControl(New form())
        form.action = strmid(catView._pathidentity, strlen(network.pathSeperator))
        li.addchild(form)

        Const recentClassName As String = "rc"
        Const recentCategoryFailedTextVar As String = "whrcft"
        Const recentCategoryDivId As String = "wh_rc"
        Const recentTopicFailedTextVar As String = "whrctt"
        Const recentTopicDivId As String = "wh_rt"
        Const hidefunctionName As String = "whhd"
        Const showFunctionName As String = "whsh"
        webctrl.var.invoke(page.inlineScript(), recentCategoryFailedTextVar, _
                           "'" + context.string(stringId.FAILEDGETCATEGORY) + "'")

        page.inlineScript().addscript(hidefunctionName, "function " + hidefunctionName + "(){" + _
                                      hideById.invoke(page.inlineScript(), "'" + recentCategoryDivId + "'") + ";" + _
                                      hideById.invoke(page.inlineScript(), "'" + recentTopicDivId + "'") + ";}")
        page.body().onclick() = hidefunctionName + "()"
        page.body().onload() = page.body().onclick()

        page.inlineScript().addscript(showFunctionName, "function " + showFunctionName + "(i){" + _
                                      stopbubble.invoke(page.inlineScript()) + ";" + _
                                      hidefunctionName + "();" + _
                                      showById.invoke(page.inlineScript(), "i") + ";}")

        Dim input As input = Nothing
        input = context.createControl(New input())
        input.type = xhtmlctrl.input.type_enum.text
        input.name = query.category
        Dim s As String = Nothing
        s = context.url().query(query.category)
        If Not isemptystring(s) Then
            input.value = s
        End If
        input.class = "t"
        attributeSetters.autocomplete(input, True)
        input.onfocus = changeInnerHtmlAndShowByIdWithAjaxCall.invoke(page.inlineScript(), _
                                          "'" + recentCategory.generateRecentCategoryAjaxLink( _
                                                    count:=config.recentDropdownListLength, last:=True) + "'", _
                                          "'" + recentCategoryDivId + "'", _
                                          failedToGetResponseText:=recentCategoryFailedTextVar)
        input.onclick = showFunctionName + "('" + recentCategoryDivId + "')"
        form.addchild(input)

        input = context.createControl(New input())
        input.type = xhtmlctrl.input.type_enum.submit
        input.value = context.string(stringId.HOMEPAGE_SEARCHCATEGORY_SUBMIT)
        input.class = "s"
        form.addchild(input)

        Dim recentCategoryDiv As div = Nothing
        recentCategoryDiv = context.createControl(New div())
        recentCategoryDiv.id = recentCategoryDivId
        recentCategoryDiv.class = recentClassName
        recentCategoryDiv.onclick = stopbubble.invoke(page.inlineScript())
        li.addchild(recentCategoryDiv)

        li = context.createControl(New colorli(page))
        ul.addchild(li)

        xmltext = context.createControl(New xmltext())
        xmltext.text = context.string(stringId.HOMEPAGE_VIEWKEY)
        li.addchild(xmltext)

        form = context.createControl(New form())
        form.action = strmid(view._pathidentity, strlen(network.pathSeperator))
        li.addchild(form)

        webctrl.var.invoke(page.inlineScript(), recentTopicFailedTextVar, _
                           "'" + context.string(stringId.FAILEDGETTOPIC) + "'")

        input = context.createControl(New input())
        input.type = xhtmlctrl.input.type_enum.text
        input.name = query.key
        s = context.url().query(query.key)
        If Not isemptystring(s) Then
            input.value = s
        End If
        input.class = "t"
        attributeSetters.autocomplete(input, True)
        input.onfocus = changeInnerHtmlAndShowByIdWithAjaxCall.invoke(page.inlineScript(), _
                                          "'" + recentTopic.generateRecentTopicAjaxLink( _
                                                    count:=config.recentDropdownListLength, last:=True) + "'", _
                                          "'" + recentTopicDivId + "'", _
                                          failedToGetResponseText:=recentTopicFailedTextVar)
        input.onclick = showFunctionName + "('" + recentTopicDivId + "')"
        form.addchild(input)

        input = context.createControl(New input())
        input.type = xhtmlctrl.input.type_enum.submit
        input.value = context.string(stringId.HOMEPAGE_VIEWKEY_SUBMIT)
        input.class = "s"
        form.addchild(input)

        Dim recentTopicDiv As div = Nothing
        recentTopicDiv = context.createControl(New div())
        recentTopicDiv.id = recentTopicDivId
        recentTopicDiv.class = recentClassName
        recentTopicDiv.onclick = stopbubble.invoke(page.inlineScript())
        li.addchild(recentTopicDiv)

        li = context.createControl(New colorli(page))
        ul.addchild(li)

        addvisitCounter(context, li)
    End Sub

    Private Sub processPagination(ByVal context As httpContext, ByVal page As xhtmlpage, ByVal root As xmlcontrol, _
                                  ByVal start As Int64, ByVal count As Int64, ByVal nomore As Boolean)
        assert(Not context Is Nothing, "context is nothing.")
        assert(Not page Is Nothing, "page is nothing.")
        assert(Not root Is Nothing, "root is nothing.")

        Dim baseurl As String = Nothing
        baseurl = strmid(context.url().path(), strlen(network.pathSeperator))
        Dim lastlink As String = Nothing
        Dim nextlink As String = Nothing
        If start > 0 Then
            lastlink = generateLink(context, baseurl, Nothing)
            If start > count Then
                lastlink = urlUtils.appendQuery(lastlink, query.first, start - count)
            End If
            If isemptystring(lastlink) Then
                lastlink = network.thislevelPathMark
            End If
        End If
        If Not nomore Then
            nextlink = urlUtils.appendQuery(generateLink(context, baseurl, Nothing), _
                                query.first, start + count)
        End If
        If count <> defaultTopicCount() Then
            If Not lastlink Is Nothing Then
                lastlink = urlUtils.appendQuery(lastlink, query.count, count)
            End If
            If Not nextlink Is Nothing Then
                nextlink = urlUtils.appendQuery(nextlink, query.count, count)
            End If
        End If
        root.addchild(preview_pagination.create(context, page, lastlink, nextlink))
    End Sub

    Private Sub processCategories(ByVal context As httpContext, ByVal page As xhtmlpage, ByVal root As xmlcontrol)
        assert(Not context Is Nothing, "context is nothing.")
        assert(Not page Is Nothing, "page is nothing.")
        assert(Not root Is Nothing, "root is nothing.")

        root.addchild(categories.create(context, page, wfileis.recentCategory.output()))
    End Sub

    Protected Overridable Function startticks() As Int64
        Return Now.Ticks()
    End Function

    Private Sub processTimeline(ByVal context As httpContext, ByVal page As xhtmlpage, ByVal root As xmlcontrol)
        assert(Not context Is Nothing, "context is nothing.")
        assert(Not page Is Nothing, "page is nothing.")
        assert(Not root Is Nothing, "root is nothing.")
        root.addchild(preview_timeline.create(context, page, startticks()))
    End Sub

    Protected MustOverride Function title() As String

    Protected Overridable Sub prepare(ByVal context As httpContext)
    End Sub

    Protected Overridable Function defaultTopicCount() As Int64
        Return config.topiccount
    End Function

    Protected NotOverridable Overrides Function processImpl(ByVal context As httpContext, _
                                                            ByRef control As xmlcontrol) As Boolean
        prepare(context)
        assert(Not context Is Nothing, "context is nothing.")
        Dim page As xhtmlpage = Nothing
        page = context.createControl(New xhtmlpage())

        page.addcsslink(cssrequest.generateCssfileLinkUrl("previewpage.css"))
        page.title().text = title()
        page.inlineStyle().addstyle("body.background-color", _
                                    "BODY{background-color:" + _
                                        Convert.ToString(colorfulControl.defaultOriginColor) + ";}")

        page.body().addchild(header.generateInstance(page, False))

        Dim content As div = Nothing
        content = context.createControl(New div())
        content.id = "ct"
        page.body().addchild(content)

        Dim leftrail As div = Nothing
        leftrail = context.createControl(New div())
        leftrail.id = "lr"
        content.addchild(leftrail)

        Dim start As Int64
        If Not context.url().queryInt64(query.first, start) Then
            start = 0
        End If
        Dim count As Int64
        If Not context.url().queryInt64(query.count, count) Then
            count = defaultTopicCount()
        End If
        Dim nomore As Boolean
        processTopics(context, page, leftrail, start, count, nomore)
        processPagination(context, page, leftrail, start, count, nomore)

        Dim rightrail As div = Nothing
        rightrail = context.createControl(New div())
        rightrail.id = "rr"
        content.addchild(rightrail)

        rightrail.addchild(context.createControl(New lpmsengi.nameLpmsControl(page, "preview_description")))

#If RETIRED Then
        Dim brand As div = Nothing
        brand = context.createControl(New div())
        brand.id = "brd"
        brand.text = context.string(stringId.HOMEPAGE_BRAND)
        rightrail.addchild(brand)
#End If
        processTimeline(context, page, rightrail)
        processCategories(context, page, rightrail)
        processDescription(context, page, rightrail)
        rightrail.addchild(context.createControl(New lpmsengi.nameLpmsControl(page, "preview_rightrail_bottom")))

        Dim div As div = Nothing
        div = context.createControl(New div())
        div.id = "wrt"
        colorfulControl.invoke(page, div)
        content.addchild(div)

        Dim xmltext As xmltext = Nothing
        xmltext = context.createControl(New xmltext())
        xmltext.text = context.string(stringId.HOMEPAGE_WRITE)
        div.addchild(xmltext)

        Dim cs As String = Nothing
        div.addchild(context.createControl(New writer(New writer.datasource(page, context, True), cs)))
        page.body().addchild(quickcomment.create(context, page, cs))

        control = page
        Return True
    End Function
End Class
